package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.*;
import com.zb.list.WorkLogListVo;
import com.zb.mapper.*;
import com.zb.result.PageUtil;
import com.zb.service.*;
import com.zb.utils.TransactionUtil;
import com.zb.utils.ZbManager;
import com.zb.vo.WorkLogVo;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 工单日志表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-09-22
 */
@Service
public class ZjWorkLogServiceImpl extends ServiceImpl<ZjWorkLogMapper, ZjWorkLog> implements ZjWorkLogService {
    @Resource
    private ZjWorkLogMapper workLogMapper;
    @Resource
    private ZjWorkLogAnnexService workLogAnnexService;
    @Resource
    private ZjWorkLog02Service workLog02Service;
    @Resource
    private ZjWorkLogAnnex02Mapper workLogAnnex02Mapper;
    @Resource
    private ZjWorkLog03Service workLog03Service;
    @Resource
    private ZjWorkLogAnnex03Mapper workLogAnnex03Mapper;
    @Resource
    private ZjWorkLog04Service workLog04Service;
    @Resource
    private ZjWorkLogAnnex04Mapper workLogAnnex04Mapper;
    @Resource
    private ZjWorkLog05Service workLog05Service;
    @Resource
    private ZjWorkLogAnnex05Mapper workLogAnnex05Mapper;
    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource(name = "asyncServiceExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 分表数量
     */
    private static int TABLE_COUNT = 5;


    // 保存工单客服操作日志
    @Override
    public void saveService(WorkLogVo logVo) {
        ZjWorkLog log = getLogData(logVo);
        log.setType(1);
        save(log, logVo.getAnnexs());
    }

    // 批量保存工单客服操作日志
    @Override
    public void saveService(List<WorkLogVo> logVos) {
        if (null == logVos || logVos.isEmpty()) {
            return;
        }
        save(logVos, 1);
    }

    @Override
    public void saveNetwork(WorkLogVo logVo) {
        ZjWorkLog log = getLogData(logVo);
        log.setType(2);
        save(log, logVo.getAnnexs());
    }

    // 批量保存工单网点操作日志
    @Override
    public void saveNetwork(List<WorkLogVo> logVos) {
        if (null == logVos || logVos.isEmpty()) {
            return;
        }
        save(logVos, 2);
    }

    @Override
    public void saveOrderUser(WorkLogVo logVo) {
        ZjWorkLog log = getLogData(logVo);
        log.setType(3);
        save(log, logVo.getAnnexs());
    }

    // 批量保存工单客户操作日志
    @Override
    public void saveOrderUser(List<WorkLogVo> logVos) {
        if (null == logVos || logVos.isEmpty()) {
            return;
        }
        save(logVos, 3);
    }

    // 保存乐开伙伴云操作日志
    @Override
    public void saveLKaiHoubanyun(WorkLogVo logVo) {
        ZjWorkLog log = getLogData(logVo);
        log.setType(5);
        save(log, null);
    }


    private ZjWorkLog getLogData(WorkLogVo logVo) {
        ZjWorkLog log = new ZjWorkLog();
        log.setId(logVo.getId());
        log.setCustAccId(logVo.getCustAccId());
        log.setWorkId(logVo.getWorkId());
        log.setName(logVo.getName());
        log.setCreateEmp(logVo.getCreateEmp());
        log.setEvent(logVo.getEvent());
        log.setContent(null == logVo.getContent()? "" : logVo.getContent());
        return log;
    }

    @Override
    public void save(ZjWorkLog log, List<String> annexs) {
        threadPoolTaskExecutor.execute(() -> {
            TransactionStatus status = platformTransactionManager.getTransaction(TransactionUtil.transactionDefinition());
            List<ZjWorkLogAnnex> logAnnexes = null;
            if (null != annexs && !annexs.isEmpty()) {
                logAnnexes = annexs.stream().map(a ->{
                    ZjWorkLogAnnex an = new ZjWorkLogAnnex();
                    an.setId(IdWorker.getId());
                    an.setCustAccId(log.getCustAccId());
                    an.setWorkLogId(log.getId());
                    an.setWorkId(log.getWorkId());
                    an.setImage(a);
                    return an;
                }).toList();
            }
            try {
                long tableIndex = log.getId() % TABLE_COUNT;
                if (0 == tableIndex) {
                    this.save(log);
                    if (null != logAnnexes && !logAnnexes.isEmpty()) workLogAnnexService.saveBatch(logAnnexes);
                }
                if (1 == tableIndex) {
                    workLog02Service.save(new ZjWorkLog02(log));
                    if (null != logAnnexes && !logAnnexes.isEmpty()) workLogAnnex02Mapper.insertBatch(logAnnexes);
                }
                if (2 == tableIndex) {
                    workLog03Service.save(new ZjWorkLog03(log));
                    if (null != logAnnexes && !logAnnexes.isEmpty()) workLogAnnex03Mapper.insertBatch(logAnnexes);
                }
                if (3 == tableIndex) {
                    workLog04Service.save(new ZjWorkLog04(log));
                    if (null != logAnnexes && !logAnnexes.isEmpty()) workLogAnnex04Mapper.insertBatch(logAnnexes);
                }
                if (4 == tableIndex) {
                    workLog05Service.save(new ZjWorkLog05(log));
                    if (null != logAnnexes && !logAnnexes.isEmpty()) workLogAnnex05Mapper.insertBatch(logAnnexes);
                }
                platformTransactionManager.commit(status);
            } catch (Exception e) {
                ZbManager.log.error("添加工单操作日志异常，提示：" + e);
                platformTransactionManager.rollback(status);
            }
        });
    }

    private void save(List<WorkLogVo> logVos, Integer type) {
        threadPoolTaskExecutor.execute(() -> {
            TransactionStatus status = platformTransactionManager.getTransaction(TransactionUtil.transactionDefinition());
            List<ZjWorkLog> logs = new ArrayList<>();
            List<ZjWorkLogAnnex> annexes = new ArrayList<>();
            List<ZjWorkLog02> log02s = new ArrayList<>();
            List<ZjWorkLogAnnex> annexe02s = new ArrayList<>();
            List<ZjWorkLog03> log03s = new ArrayList<>();
            List<ZjWorkLogAnnex> annexe03s = new ArrayList<>();
            List<ZjWorkLog04> log04s = new ArrayList<>();
            List<ZjWorkLogAnnex> annexe04s = new ArrayList<>();
            List<ZjWorkLog05> log05s = new ArrayList<>();
            List<ZjWorkLogAnnex> annexe05s = new ArrayList<>();
            ZjWorkLog log = null;
            List<ZjWorkLogAnnex> ans = new ArrayList<>();
            ZjWorkLogAnnex annex = null;
            long tableIndex = 0L;
            for (WorkLogVo logVo : logVos) {
                log = getLogData(logVo);
                log.setType(type);

                ans.clear();
                if (null != logVo.getAnnexs() && !logVo.getAnnexs().isEmpty()) {
                    for (String s : logVo.getAnnexs()) {
                        annex = new ZjWorkLogAnnex();
                        annex.setId(IdWorker.getId());
                        annex.setCustAccId(log.getCustAccId());
                        annex.setWorkLogId(log.getId());
                        annex.setWorkId(log.getWorkId());
                        annex.setImage(s);
                        ans.add(annex);
                    }
                }

                tableIndex = log.getId() % TABLE_COUNT;
                if (0 == tableIndex) {
                    logs.add(log);
                    annexes.addAll(ans);
                }
                if (1 == tableIndex) {
                    log02s.add(new ZjWorkLog02(log));
                    annexe02s.addAll(ans.stream().map(an -> {
                        return new ZjWorkLogAnnex02(an);
                    }).toList());
                }
                if (2 == tableIndex) {
                    log03s.add(new ZjWorkLog03(log));
                    annexe03s.addAll(ans.stream().map(an -> {
                        return new ZjWorkLogAnnex03(an);
                    }).toList());
                }
                if (3 == tableIndex) {
                    log04s.add(new ZjWorkLog04(log));
                    annexe04s.addAll(ans.stream().map(an -> {
                        return new ZjWorkLogAnnex04(an);
                    }).toList());
                }
                if (4 == tableIndex) {
                    log05s.add(new ZjWorkLog05(log));
                    annexe05s.addAll(ans.stream().map(an -> {
                        return new ZjWorkLogAnnex05(an);
                    }).toList());
                }
            }

            try {
                if (!logs.isEmpty()) {
                    this.saveBatch(logs);
                    if (!annexes.isEmpty()) workLogAnnexService.saveBatch(annexes);
                }
                if (!log02s.isEmpty()) {
                    workLog02Service.saveBatch(log02s);
                    if (!annexe02s.isEmpty()) workLogAnnex02Mapper.insertBatch(annexe02s);
                }
                if (!log03s.isEmpty()) {
                    workLog03Service.saveBatch(log03s);
                    if (!annexe03s.isEmpty()) workLogAnnex03Mapper.insertBatch(annexe03s);
                }
                if (!log04s.isEmpty()) {
                    workLog04Service.saveBatch(log04s);
                    if (!annexe04s.isEmpty()) workLogAnnex04Mapper.insertBatch(annexe04s);
                }
                if (!log05s.isEmpty()) {
                    workLog05Service.saveBatch(log05s);
                    if (!annexe05s.isEmpty()) workLogAnnex05Mapper.insertBatch(annexe05s);
                }
                platformTransactionManager.commit(status);
            } catch (Exception e) {
                ZbManager.log.error("添加工单操作日志异常，提示：" + e);
                platformTransactionManager.rollback(status);
            }
        });
    }

    // 根据工单ID获取最新进展
    @Override
    public WorkLogListVo getOrderLastLogByWorkId(Long workId) {
        ZjWorkLog log = workLogMapper.getOrderLastLogByWorkId(workId);
        List<ZjWorkLogAnnex> logAnnexes = workLogAnnexService.getByWorkLogIds(Arrays.asList(log.getId()));
        return getLogData(log, logAnnexes);
    }

    // 根据工单ID获取工单操作记录列表
    @Override
    public Map<String, Object> getOrderLogList(Long workId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        List<ZjWorkLog> logs = workLogMapper.getOrderLogList(workId, pageUtil);
        List<Long> logIds = logs.stream().map(ZjWorkLog::getId).toList();
        List<ZjWorkLogAnnex> logAnnexes = workLogAnnexService.getByWorkLogIds(logIds);

        return PageUtil.pageList(pageUtil.getPage(), pageUtil.getLimit(), workLogMapper.getOrderLogListCount(workId),
                logs.stream().map(log -> {
                    return getLogData(log, logAnnexes);
                }));
    }

    private WorkLogListVo getLogData(ZjWorkLog log, List<ZjWorkLogAnnex> logAnnexes) {
        WorkLogListVo vo = new WorkLogListVo();
        BeanUtil.copyProperties(log, vo);
        vo.setCreateTime(log.getGmtCreate());
        vo.setType(Objects.equals("1", vo.getType()) ? "客服" :
                Objects.equals("2", vo.getType()) ? "服务商" :
                        Objects.equals("3", vo.getType()) ? "客户" :
                        Objects.equals("4", vo.getType()) ? "品牌商家" :
                                Objects.equals("5", vo.getType()) ? "乐开伙伴云" :
                                        Objects.equals("6", vo.getType()) ? "系统提示" : "客服");
        vo.setImages(logAnnexes.stream().filter(f -> Objects.equals(f.getWorkLogId(), vo.getId())).map(ZjWorkLogAnnex::getImage).toList());
        return vo;
    }

    public static void main(String[] args) {
        int count = 5;
        for (int i = 0; i < 50; i++) {
            long id = IdWorker.getId();
            long d = id % count;
            System.out.println(id + " ======>>>> " + d);
        }
    }

}
